home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / drivers / mscdex / testdrv / support.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-25  |  10.3 KB  |  439 lines

  1. /*
  2. ** TESTDRV
  3. **
  4. ** Device Driver Test for MSCDEX compatible CD-ROM
  5. **
  6. ** Note: several routines taken from audio.c and speed.c
  7. **
  8. ** FILE: support.c
  9. ** 
  10. ** HISTORY:
  11. **   10/01/90 Final (v1.0) -by- JYG
  12. **   12/06/91 Revision Siddhartha Roy 
  13. */
  14.  
  15. #include<ctype.h>
  16. #include<malloc.h>
  17.  
  18. #include "test.h"
  19.  
  20. static union   REGS    inregs;
  21. static union   REGS    outregs;
  22. static struct  SREGS   segregs;
  23.  
  24. /*
  25. ** int VolLabel( WORD iDrive, char * szName )
  26. ** Returns the volume label of iDrive in szName
  27. */
  28.  
  29. char * VolLabel( iDrive, szName )
  30. WORD iDrive;
  31. char * szName;
  32. {
  33.     char * szPath = "C:\*.*";
  34.     struct find_t Buf;
  35.     extern WORD iFirstDrvLetter;
  36. #ifdef DEBUG
  37. printf ( "\n Drive # %u, FirstDrive # %u\n", iDrive, iFirstDrvLetter );
  38. #endif
  39.     sprintf( szPath,"%c:\\*.*",(char) (iDrive + iFirstDrvLetter) + 'A' );
  40.  
  41. #ifdef DEBUG
  42. printf ( "\n Using Path : %s \n",szPath );
  43. #endif
  44.  
  45.     _dos_findfirst( szPath,_A_VOLID,&Buf );
  46.     
  47.     strcpy ( szName,Buf.name );
  48.  
  49. #ifdef DEBUG
  50. printf ( "\n Volume Label : %s\n", szName);
  51. #endif
  52.     
  53.     return ( szName );
  54.  
  55. }
  56.  
  57. /*
  58. ** Fatal Program errors
  59. */
  60.  
  61. void fatalError( msg )
  62.     char * msg;
  63. {
  64.     fprintf( stdout,"\n%s: Fatal Error, %s \n",PROGNAME,msg );
  65.     exit( 1 );
  66. }
  67.  
  68. // It is the responsibilty of the device driver writer to set the 
  69. // bits properly in the status word.  Here we simply give the info
  70. // as to whether BUSY/DONE/ERROR are set or not.
  71.  
  72. WORD    InterpStatus( wStatus )
  73. WORD    wStatus;
  74. {
  75.     if ( ERRORBIT&wStatus ) printf( "ERROR 0x%0.2x:",wStatus&ERRORMASK );
  76.     if ( BUSYBIT&wStatus ) printf( "BUSY:" );
  77.     if ( DONEBIT&wStatus ) printf( "DONE:" );
  78.     return wStatus;
  79. }
  80.  
  81. /*
  82. ** Ask(char *) 
  83. ** - prompts the user for a yes/no question expecting 
  84. **   'Y' (default on return) returns TRUE for yes, FALSE
  85. **  for no
  86. */  
  87.  
  88. char Ask ( chQuestion )
  89. char * chQuestion;
  90. {
  91.     char chResponse;
  92.     extern FLAG fInteract;
  93.     
  94.     do
  95.     {
  96.         printf( "\n\t\t%s? [Yncq] ",chQuestion );
  97.         chResponse = (char)getche();
  98.         if ( chResponse == ' ' || chResponse == '\n' )
  99.             return TRUE;
  100.         switch (tolower(chResponse))
  101.         {
  102.             case 'y':
  103.                 return TRUE;
  104.                 break;
  105.             case 'c':
  106.                 fInteract = FALSE;
  107.                 return TRUE;
  108.                 break;
  109.             case 'q':
  110.                 fprintf(stdout,"\n\tExiting...........");
  111.                 exit(1);
  112.                 break;
  113.             case 'n':
  114.                 return FALSE;
  115.                 break;
  116.             default:
  117.                 break;
  118.         }
  119.                 
  120.     }
  121.     while ( TRUE );
  122. }
  123.  
  124. /*
  125. ** Msg(BYTE,BYTE,const char *,char *)
  126. ** - Generic informative pretty print
  127. */
  128.  
  129. void Msg(sLabel, szStat,szMsg)
  130. ReqName sLabel;
  131. char *szStat,*szMsg;
  132. {
  133.     if (sLabel.bCmd != 0)
  134.         printf("\n%d:%d\t%s\t%s\t %s",sLabel.bCmd,sLabel.bSubCmd,szStat,
  135.             sLabel.CmdName,szMsg);
  136.     else
  137.         printf("\n%d\t%s\t%s %s",sLabel.bSubCmd,szStat,sLabel.CmdName,szMsg);
  138. }
  139.  
  140. /*
  141. ** ErrMsg(ReqName,char *)
  142. ** - Pretty Print Standard Error Message with error tally increment
  143. */
  144. void    ErrMsg(sLabel,szSt)
  145. ReqName sLabel;
  146. char    *szSt;
  147. {
  148.     extern WORD cwErrors;
  149.     cwErrors++;
  150.     Msg(sLabel,"-ERROR-",szSt);
  151. }
  152.  
  153. /*
  154. ** WarningMsg(BYTE,BYTE,char *)
  155. ** - Pretty Print Standard Warning Message with warning tally increment
  156. **
  157. */
  158. void    WarningMsg(sLabel,szSt)
  159. ReqName sLabel;
  160. char    *szSt;
  161. {
  162.     extern WORD cwWarnings;
  163.     cwWarnings++;
  164.     Msg(sLabel,"WARNING",szSt);
  165. }
  166.  
  167. /*
  168. ** ReportMsg(BYTE,BYTE,char *)
  169. ** - Pretty Print Standard Report Message
  170. */
  171. void    ReportMsg(sLabel,szSt)
  172. ReqName sLabel;
  173. char    *szSt;
  174. {
  175.     Msg(sLabel,"",szSt);
  176. }
  177.  
  178. /*
  179. ** ErrorTest(WORD, BYTE, BYTE, char *)
  180. ** - Check status word and look up error code if the Error Bit is set
  181. */
  182. WORD    ErrorTest(wStatus,sLabel)
  183. WORD    wStatus;
  184. ReqName sLabel;
  185. {
  186.     extern WORD cwErrors;
  187.     // Device Driver Error Codes
  188.  
  189.     static char *szErrorCodes[] = {
  190.         " Write-protect violation",
  191.         " Unknown unit",
  192.         " Drive not ready",
  193.         " Unknown command",
  194.         " CRC error",
  195.         " Bad drive request structure length",
  196.         " Seek error",
  197.         " Unknown media",
  198.         " Sector not found",
  199.         " Printer out of paper",
  200.         " Write fault",
  201.         " Read fault",
  202.         " General failure",
  203.         " --reserved error code--",
  204.         " --reserved error code--",
  205.         " Invalid disk change"
  206.     };
  207.  
  208.     if (wStatus & ERRORBIT)
  209.     {
  210.         cwErrors++;
  211.         Msg(sLabel,"*ERROR*",szErrorCodes[ERRORMASK&wStatus]);
  212.     }
  213.     return (wStatus);
  214. }
  215.  
  216.  
  217. /*
  218. ** PrintAudInfo(AudInfo_Rec)
  219. ** - Pretty Print AudInfo_Rec's
  220. */
  221.  
  222. void PrintAudInfo(ainf)
  223. AudInfo_Rec ainf;
  224. {
  225.     printf("\nAudioInfo: Channel Status\n");
  226.     printf("Channel %d mapped to channel 0 vol %d\n",ainf.in0,ainf.vol0);
  227.     printf("Channel %d mapped to channel 1 vol %d\n",ainf.in1,ainf.vol1);
  228.     printf("Channel %d mapped to channel 2 vol %d\n",ainf.in2,ainf.vol2);
  229.     printf("Channel %d mapped to channel 3 vol %d\n",ainf.in3,ainf.vol3);
  230. }
  231.  
  232. /* hexDump(BYTE *, WORD)
  233. **
  234. ** Quick Hex dump in 16 columns.
  235. **
  236. */
  237.  
  238. void HexDump(pchBuf,nbytes)
  239. BYTE far *pchBuf;
  240. WORD    nbytes;
  241. {
  242.     WORD iIn,iOut,cNum,cChar;
  243.     extern FILE *pOutFile;
  244.     printf("\n\n%d bytes\n",nbytes);
  245.     for (iIn=0;iIn<79;iIn++) fputc('-',pOutFile);
  246.     fputc('\n',pOutFile);
  247.     for (iOut=0,cNum=0,cChar=0;cNum < nbytes;iOut++) {
  248.  
  249.         fprintf(pOutFile,"%.4X\t",cChar);
  250.  
  251.         for (iIn=0; iIn<16;iIn++,cNum++)
  252.             if (cNum<nbytes)
  253.                 fprintf(pOutFile,"%0.2X ",(BYTE)pchBuf[iIn+iOut*16]);
  254.             else fprintf(pOutFile,"   ");
  255.  
  256.         fprintf(pOutFile,"   ");
  257.  
  258.         for (iIn=0; iIn<16;iIn++,cChar++) {
  259.             if (isgraph(pchBuf[iIn+iOut*16])&&cChar<nbytes)
  260.                 fputc(pchBuf[iIn+iOut*16],pOutFile);
  261.             else fputc(' ',pOutFile);
  262.         };
  263.         fputc('\n',pOutFile);
  264.     };
  265.     for (iIn=0;iIn<79;iIn++) fputc('-',pOutFile);
  266.     fputc('\n',pOutFile);
  267. }
  268.  
  269. /*
  270. ** (char far*) my_malloc (long)
  271. **
  272. ** Allocate the far memory for the transfer buffer.
  273. ** - from speed.c
  274. */
  275.  
  276. BYTE _far *my_malloc( how_much )
  277. DWORD how_much;
  278. {
  279.     BYTE _far *buffer=0;
  280.  
  281.     inregs.x.ax = 0x4800;
  282.     inregs.x.bx = (short)(how_much >> 4) + 1;
  283.     int86x(0x21, &inregs, &outregs, &segregs);
  284.  
  285.     if ( outregs.x.cflag == 0 )
  286.     {
  287.         buffer = (BYTE _far *)MAKELONG( 0, outregs.x.ax );
  288.         _fmemset(buffer,0,(size_t)how_much);
  289.     }
  290.     else
  291.     {  
  292.    printf("\nSize of largest available block is %d \n",outregs.x.bx);
  293.         fatalError("MALLOC FAILURE");
  294.    }
  295.     return( buffer );
  296. }
  297.  
  298.  
  299. /* Free the far memory for the xfer buffer.
  300. */
  301. void my_free( buffer )
  302. BYTE _far *buffer;
  303. {
  304.     inregs.x.ax = 0x4900;
  305.     segregs.es  = HIWORD( (DWORD)buffer );
  306.     int86x(0x21, &inregs, &outregs, &segregs);
  307. }
  308.  
  309. /* 
  310. ** PrintRed(DWORD) - Pretty print a redbook addr
  311. */
  312. void PrintRed(lSector)
  313. DWORD lSector;
  314.  
  315. {
  316.     printf("%u:%u:%u",HIWORD(lSector)&0xff,
  317.         LOWORD(lSector)>>8,LOWORD(lSector)&0xff);
  318. }
  319.  
  320. /*
  321. ** RedDiff(DWORD,DWORD)
  322. ** - given two redbook addresses, returns their difference
  323. **   in Redbook time
  324. */
  325. DWORD RedDiff(lSectorA,lSectorB)
  326. DWORD lSectorA,lSectorB;
  327. {
  328.     if (lSectorA > lSectorB)
  329.         return hsg2red((red2hsg(lSectorA) - red2hsg(lSectorB)));
  330.     else
  331.         return hsg2red((red2hsg(lSectorB) - red2hsg(lSectorA)));
  332. }
  333.  
  334. /* bcd2bin() -
  335. **
  336. ** DESCRIPTION
  337. **  Converts BCD to binary. BCD breaks a byte into two 4-bit
  338. **  nibbles where each ranges from 0-9. BCD can represent 0-99
  339. **  whereas binary does 0-255. If the value passed in is an
  340. **  illegal BCD value, we return 0xff
  341. */
  342. BYTE bcd2bin(c)
  343. BYTE    c;
  344. {
  345.     if ((c & 0x0f) > 0x09)
  346.         return(0xff);
  347.     if ((c & 0xf0) > 0x90)
  348.         return(0xff);
  349.     return ((BYTE)(((c&(BYTE)0xf0)>>4) * 10) + (BYTE)(c&(BYTE)0x0f));
  350. }
  351.  
  352. /* red2hsg() -
  353. **
  354. ** DESCRIPTION
  355. **  Converts a binary red book address to high sierra addressing
  356. **  The msb of the red book is always zero, the next less significant
  357. **  byte is the minute (0-59+), then second (0-59) and lsb is the
  358. **  frame (0-75). The conversion is
  359. **      hsg = min * 60 * 75 + sec * 75 + frame;
  360. */
  361. DWORD red2hsg(l)
  362. DWORD   l;
  363. {
  364.     return((DWORD) (HIWORD(l) & 0xff) * 60 * 75 +
  365.         (DWORD) (LOWORD(l) >> 8) * 75 +
  366.         (DWORD) (LOWORD(l) & 0xff));
  367. }
  368. /* hsg2red(DWORD)
  369. **
  370. ** Does the opposite of red2hsg()
  371. **
  372. **
  373. */
  374. DWORD hsg2red(l)
  375. DWORD   l;
  376. {
  377.     DWORD min,sec,fra;
  378.     min = l/(60*75);
  379.     sec = (l%(60*75))/75;
  380.     fra = (l%(60*75))%75;
  381.     return (0x00ffffff&((min<<16)|(sec<<8)|fra));
  382. }
  383.  
  384. /* find_drivers() -
  385. **
  386. **  Using INT 2Fh with AH=15h (the MSCDEX function request interface)
  387. **  we can ask MSCDEX for the number and location of all CDROM
  388. **  device drivers on the system.
  389. */
  390.  
  391. void find_drivers(Dev_Tbl)
  392. Dev_List    *Dev_Tbl;
  393. {
  394.     
  395.     extern WORD cwNumDrives,iFirstDrvLetter;
  396.  
  397.     union REGS  inregs;
  398.     union REGS  outregs;
  399.     struct SREGS    segregs;
  400.  
  401.     BYTE far    *d = (BYTE far *) Dev_Tbl;
  402.     Dev_Hdr far *sdev;
  403.     uint        i;
  404.  
  405.     inregs.x.ax = 0x1500;       // Get Number of CDROM drive letters
  406.     inregs.x.bx = 0;        // Init to zero
  407.     int86(0x2f, &inregs, &outregs);
  408.  
  409.         // If number of drives returned is still 0, then MSCDEX
  410.         // is not installed.
  411.  
  412.     if (outregs.x.bx == 0)
  413.         fatalError("\tMSCDEX not installed, Exiting.");
  414.  
  415.     cwNumDrives  = outregs.x.bx;
  416.     iFirstDrvLetter = outregs.x.cx;
  417.  
  418.     printf("\tDEVICE DRIVER INFORMATION:: \n");
  419.     printf("\t%d drive(s) found  starting at %c:\n", cwNumDrives,
  420.         iFirstDrvLetter + 'A');
  421.  
  422.     inregs.x.ax = 0x1501;       // Get CDROM drive letter device list
  423.     inregs.x.bx = LOWORD(d);
  424.     segregs.es  = HIWORD(d);
  425.     int86x(0x2f, &inregs, &outregs, &segregs);
  426.  
  427.     if (outregs.x.cflag)
  428.         fatalError("MSCDEX not present, Exiting.");
  429.  
  430.     for (i = 0; i < cwNumDrives; i++) {
  431.         printf("\tDrive %c:%d unit %d / Device Header Address :: 0x%lx \n", i + iFirstDrvLetter + 'A',
  432.             i,Dev_Tbl[i].sub_unit,Dev_Tbl[i].dev_addr);
  433.         sdev = Dev_Tbl[i].dev_addr;
  434.         printf("\tDrive Name (obtained via Device Header) :: '%8Fs'\n", sdev->sdevname);
  435.    printf("\tDevice Attributes :: %x \n",(Dev_Tbl[i].dev_addr)->sdevatt);
  436.     }
  437. }
  438.  
  439.